package org.gap.wizards.utils;

import java.awt.Point;
import java.lang.reflect.Field;

import org.gap.jseed.injection.annotation.Singleton;
import org.gap.wizards.views.ViewPlatform;

import net.slashie.libjcsi.CSIColor;
import net.slashie.libjcsi.CharKey;
import net.slashie.libjcsi.ConsoleSystemInterface;

@Singleton
public class SlashieConsole implements ViewPlatform {
	private static final int SCREEN_WIDTH = 120;
	private static final int MIN_PER_LINE = 72;
	private ConsoleSystemInterface csi;
	private Color background = Color.BLACK;

	public SlashieConsole(ConsoleSystemInterface csi) {
		this.csi = csi;
	}

	@Override
	public void print(int x, int y, String text) {
		print(x, y, Color.WHITE, text);
	}
	
	@Override
	public void print(int x, int y, Color color, String text) {
		try {
			Field foregroundColor = CSIColor.class.getDeclaredField(color.name());
			Field backgroundColor = CSIColor.class.getDeclaredField(this.background.name());
			
			CSIColor foreground = (CSIColor)foregroundColor.get(null);
			CSIColor background = (CSIColor)backgroundColor.get(null);
			csi.print(x, y, text, foreground, background);
		} catch (Exception e) {
			System.err.println("Cannot get color: " + e);
		}
	}
	
	@Override
	public void setBackground(Color color) {
		this.background = color;
	}
	
	@Override
	public void print(int x, int y, Color color, char character) {
		print(x, y, color, character + "");
	}
	
	@Override
	public Color peekColor(Point point) {
		int colorCode = csi.peekColor(point.x, point.y);
		String string = CSIColor.getColorFromCode(colorCode).toString();
		return Color.valueOf(string);
	}
	
	@Override
	public char peekSymbol(Point point) {
		return csi.peekChar(point.x, point.y);
	}
	
	@Override
	public void printMessageWindow(String introduction) {
		String[] split = introduction.split("\n");
		int lines = getLineCount(split);
		int start = (30 - lines) / 2;
		int endSeg = MIN_PER_LINE;
		int startSeg = 0;
		for (String each : split) {
			while (endSeg < each.length()) {
				endSeg = findNextSpace(each, endSeg);
				String text = each.substring(startSeg, endSeg).trim();
				print((SCREEN_WIDTH - 76) / 2, start, text);
				startSeg = endSeg + 1;
				endSeg = startSeg + MIN_PER_LINE;
				start++;
			}
			String text = each.substring(startSeg).trim();
			print((SCREEN_WIDTH - 76) / 2, start, text);
			start += 2;
			
			startSeg = 0;
			endSeg = MIN_PER_LINE;
		}
		print(60, start + 4, "Press (space) to continue.");
	}

	private int findNextSpace(String each, int nextSeg) {
		char charAt = each.charAt(nextSeg);
		while (charAt != '.' && charAt != ' ') {
			nextSeg++;
			charAt = each.charAt(nextSeg);
		}
		return nextSeg;
	}

	private int getLineCount(String[] split) {
		int lines = split.length;
		for (String each : split) {
			if (each.length() > 75) {
				lines += each.length() / 75;
			} else {
				lines++;
			}
		}
		return lines;
	}
	
	@Override
	public CharKey getKeyPressed() {
		return new CharKey(readInput());
	}
	
	@Override
	public void clear() {
		csi.cls();
	}
	
	@Override
	public void saveBuffer() {
		csi.saveBuffer();
	}
	
	@Override
	public void restore() {
		csi.restore();
	}
	
	@Override
	public void refresh() {
		csi.refresh();
	}
	
	@Override
	public int readInput() {
		return csi.inkey().code;
	}
	
	@Override
	public String toString() {
		return csi.toString();
	}
}
